#include "RtcInitHelper.h"

#include <hc32_ll_utility.h>
#include <string.h>
#include <time.h>

#include "ClkInitHelper.h"
#include "I2cInitHelper.h"
#include "SimpleCompletion.h"

char time_buf[64];
Rtc_Ctrl_Task_Def ext_rtc_ctrl;
// 内部RTC状态
uint8_t inner_rtc_status;
// 外部RTC时间记录
Rtc_Time_Def ext_rtc_time;
// 内部RTC时间记录
Rtc_Time_Def inner_rtc_time;

//RTC Config
void App_RTCCfg(void) {
  stc_rtc_init_t stcRtcInit;
  stc_rtc_date_t stcRtcDate;
  stc_rtc_time_t stcRtcTime;
  stc_rtc_alarm_t stcRtcAlarm;

  /* Reset RTC counter */
  if (LL_ERR_TIMEOUT != RTC_DeInit()) {
    /* Configure structure initialization */
    (void) RTC_StructInit(&stcRtcInit);

    /* Configuration RTC structure */
    stcRtcInit.u8ClockSrc = RTC_CLK_SRC_XTAL32;
    stcRtcInit.u8HourFormat = RTC_HOUR_FMT_24H;
    stcRtcInit.u8IntPeriod = RTC_INT_PERIOD_PER_HOUR;
    stcRtcInit.u8ClockCompen = RTC_CLK_COMPEN_DISABLE;
    (void) RTC_Init(&stcRtcInit);

    /* Configuration alarm clock time */
    stcRtcAlarm.u8AlarmHour = 0x23U;
    stcRtcAlarm.u8AlarmMinute = 0x55U;
    stcRtcAlarm.u8AlarmWeekday = RTC_ALARM_WEEKDAY_SUNDAY | RTC_ALARM_WEEKDAY_MONDAY | RTC_ALARM_WEEKDAY_TUESDAY | RTC_ALARM_WEEKDAY_WEDNESDAY | RTC_ALARM_WEEKDAY_THURSDAY | RTC_ALARM_WEEKDAY_FRIDAY | RTC_ALARM_WEEKDAY_SATURDAY;
    stcRtcAlarm.u8AlarmAmPm = RTC_HOUR_24H;
    (void) RTC_SetAlarm(RTC_DATA_FMT_BCD, &stcRtcAlarm);
    RTC_AlarmCmd(ENABLE);

    /* Update date and time */
    /* Date configuration */
    stcRtcDate.u8Year = 24U;
    stcRtcDate.u8Month = RTC_MONTH_JANUARY;
    stcRtcDate.u8Day = 1U;
    stcRtcDate.u8Weekday = RTC_WEEKDAY_MONDAY;

    /* Time configuration */
    stcRtcTime.u8Hour = 00U;
    stcRtcTime.u8Minute = 0U;
    stcRtcTime.u8Second = 0U;
    stcRtcTime.u8AmPm = RTC_HOUR_12H_AM;

    if (LL_OK != RTC_SetDate(RTC_DATA_FMT_DEC, &stcRtcDate)) {
      return;
    }

    if (LL_OK != RTC_SetTime(RTC_DATA_FMT_DEC, &stcRtcTime)) {
      return;
    }
    /* Enable RTC interrupt */
    RTC_IntCmd(RTC_INT_PERIOD, ENABLE);
    /* Startup RTC count */
    RTC_Cmd(ENABLE);

    // 标记内部RTC已被初始化
    STATU_SET(inner_rtc_status, RTC_INITED);
  }
}

// 写入内部RTC
rt_err_t Write_Rtc_Data_Time(Rtc_Time_Def *ext_rtc_time) {
  // rtc 时间结构体
  stc_rtc_time_t pstcRtcTime;
  pstcRtcTime.u8Hour = ext_rtc_time->hour;
  pstcRtcTime.u8Minute = ext_rtc_time->minute;
  pstcRtcTime.u8Second = ext_rtc_time->second;
  pstcRtcTime.u8AmPm = RTC_HOUR_24H;
  RTC_SetTime(RTC_DATA_FMT_DEC, &pstcRtcTime);
  SWDT_FeedDog();

  // 设置日期
  stc_rtc_date_t pstcRtcDate;
  pstcRtcDate.u8Year = ext_rtc_time->year;
  pstcRtcDate.u8Month = ext_rtc_time->month;
  pstcRtcDate.u8Day = ext_rtc_time->day;
  //pstcRtcDate.u8Weekday = RTC_WEEKDAY_WEDNESDAY;
  RTC_SetDate(RTC_DATA_FMT_DEC, &pstcRtcDate);
  //LL_PERIPH_WP(LL_PERIPH_ALL);
  SWDT_FeedDog();

  return RT_EOK;
}// 写入内部RTC

// 读写保护
rt_err_t Sd3078_Write_Enable(void) {
  if (STATU_GET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_WRITEABLE)) {
    return RT_EOK;
  } else {
    // 锁定资源。
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return LL_ERR_BUSY;
      }
      get_mutex++;
    }

    memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 2;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_thread_mdelay(2);

    //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3] | 0x80;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_thread_mdelay(2);

    //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] |= 0x84;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_thread_mdelay(2);

    // 打印写结果。正式使用时候注释掉
    memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 2;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_kprintf("get 3078 reg 0x%02X,0x%02X 0x%02X 0x%02X\n", 0x0F, 0x10, ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3]);

    STATU_SET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_WRITEABLE);

    rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
    return RT_EOK;
  }
}

rt_err_t Sd3078_Write_Disable(void) {
  if (STATU_GET_NOT(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_WRITEABLE)) {
    return RT_EOK;
  } else {
    // 锁定资源。
    uint8_t get_mutex = 0;
    while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
      if (get_mutex >= 3) {
        return LL_ERR_BUSY;
      }
      get_mutex++;
    }
    memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 2;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[4] = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2];
    rt_thread_mdelay(2);

    //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_RESET(i2c1_ctrl.data_buf[3], 0x84);
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_thread_mdelay(2);

    //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_RESET(i2c1_ctrl.data_buf[4], 0x80);
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_thread_mdelay(2);

    // 打印写结果。正式使用时候注释掉
    memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
    ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x0F;
    ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
    ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 2;
    I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
    rt_kprintf("get 3078 reg 0x%02X,0x%02X 0x%02X 0x%02X\n", 0x0F, 0x10, ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3]);

    STATU_RESET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_WRITEABLE);

    rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
    return RT_EOK;
  }
}// 读写保护

// 设置RTC时间
rt_err_t Sd3078_Write_Data_Time(uint8_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x00;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = second;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3] = minute;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[4] = hour | 0x80;// 0x80就是24小时制，不加就是12小时制
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[5] = 0x01;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[6] = day;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[7] = month;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[8] = year;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 8;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
  return RT_EOK;
}// 设置RTC时间

// 读取RTC时间
rt_err_t Sd3078_Read_Data_Time(Rtc_Time_Def *obj) {
  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x00;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 7;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);

  rt_err_t res = RT_EOK;

  if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[8] == 0) {
    res = RT_ERROR;
  } else if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[7] == 0 || ext_rtc_ctrl.i2c_ctrl_obj->data_buf[7] > 12) {
    res = RT_ERROR;
  } else if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[6] == 0 || ext_rtc_ctrl.i2c_ctrl_obj->data_buf[6] > 31) {
    res = RT_ERROR;
  } else if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[4] > 23) {
    res = RT_ERROR;
  } else if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3] > 59) {
    res = RT_ERROR;
  } else if (ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] > 59) {
    res = RT_ERROR;
  }

  if (res == RT_EOK) {
    STATU_RESET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[4], 0x80);

    obj->year = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[8];
    obj->month = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[7];
    obj->day = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[6];
    obj->hour = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[4];
    obj->minute = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[3];
    obj->second = ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2];
  }

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
  return res;
}// 读取RTC时间

// 开启32.768K频率输出
rt_err_t Sd3078_Start_32K(Rtc_Time_Def *obj) {
  rt_err_t res = RT_EOK;

  // 如果已经打开就不做操作
  if (STATU_GET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_32K_NVIC)) {
    return res;
  }

  // 关闭写保护
  Sd3078_Write_Enable();

  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_SET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x40);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));

  Sd3078_Write_Disable();
  STATU_SET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_32K_NVIC);
  return res;
}// 开启32.768K频率输出

// 关闭32.768K频率输出
rt_err_t Sd3078_Stop_32K(Rtc_Time_Def *obj) {
  rt_err_t res = RT_EOK;

  // 如果已经打开就不做操作
  if (STATU_GET_NOT(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_32K_NVIC)) {
    return res;
  }
  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  //memset(i2c1_ctrl.data_buf, 0, sizeof(i2c1_ctrl.data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_RESET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x40);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));

  STATU_RESET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_32K_NVIC);
  return res;
}// 关闭32.768K频率输出

// 初始化秒中断
rt_err_t Sd3078_Init_Sec_Intc(void) {
  rt_err_t res = RT_EOK;

  // 如果已经打开就不做操作
  if (STATU_GET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_INIT_PRE_TIMER_NVIC)) {
    return res;
  }

  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  // 设置中断类型为频率中断
  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_SET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x20);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  // 设置频率中断的频率为1秒
  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x11;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_SET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x0F);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
  STATU_SET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_INIT_PRE_TIMER_NVIC);
  return res;
}// 初始化秒中断

// 启动初始化秒中断
rt_err_t Sd3078_Start_Sec_Intc(void) {
  rt_err_t res = RT_EOK;

  // 如果已经打开就不做操作
  if (STATU_GET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_PRE_TIMER_NVIC)) {
    return res;
  }

  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  // 打开中断输出
  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_SET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x01);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
  STATU_SET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_PRE_TIMER_NVIC);
  return res;
}// 启动初始化秒中断

// 关闭初始化秒中断
rt_err_t Sd3078_Stop_Sec_Intc(void) {
  rt_err_t res = RT_EOK;

  // 如果已经打开就不做操作
  if (STATU_GET_NOT(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_PRE_TIMER_NVIC)) {
    return res;
  }

  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  // 打开中断输出
  memset(ext_rtc_ctrl.i2c_ctrl_obj->data_buf, 0, sizeof(ext_rtc_ctrl.i2c_ctrl_obj->data_buf));
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 1;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 1;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[1] = 0x10;
  ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2] = STATU_RESET(ext_rtc_ctrl.i2c_ctrl_obj->data_buf[2], 0x01);
  ext_rtc_ctrl.i2c_ctrl_obj->send_data_len = 2;
  ext_rtc_ctrl.i2c_ctrl_obj->receive_data_len = 0;
  I2C_Master_Translate_IT(ext_rtc_ctrl.cm_i2c, ext_rtc_ctrl.i2c_ctrl_obj, RTC_3027_ADDR);
  rt_thread_mdelay(2);

  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));
  STATU_RESET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_PRE_TIMER_NVIC);
  return res;
}// 关闭初始化秒中断


rt_err_t Init_Rtc_Time_Obj(Rtc_Time_Def *obj) {

  // 如果对象还没被创建，就创建一个对象
  if (obj == NULL) {
    obj = (Rtc_Time_Def *) rt_malloc(sizeof(Rtc_Time_Def));
  }

  obj->Build_Rtc_Time_Str = Build_Rtc_Time_Str_Interface;
  obj->Build_Innner_Rtc_Time = Build_Innner_Rtc_Time_Interface;
  obj->Read_Ext_Rtc_Time = Read_Ext_Rtc_Time_Interface;

  return RT_EOK;
}

// 构建iso时间字符串
rt_err_t Build_Rtc_Time_Str_Interface(Rtc_Time_Def *obj) {

  size_t str_index = 0;
  char str_buf[12];
  size_t str_buf_size = 0;
  obj->iso_time_str[str_index++] = '2';
  obj->iso_time_str[str_index++] = '0';
  // 填充年
  str_buf_size = itoa(obj->year, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = '-';
  // 月份
  str_buf_size = itoa(obj->month, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = '-';
  // 日
  str_buf_size = itoa(obj->day, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = 'T';
  // 小时
  str_buf_size = itoa(obj->hour, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = ':';
  // 分钟
  str_buf_size = itoa(obj->minute, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = ':';
  // 秒
  str_buf_size = itoa(obj->second, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = '.';
  // 毫秒
  str_buf_size = itoa(obj->millisecond, str_buf, 0);
  memcpy(obj->iso_time_str, str_buf, 2);
  str_index += str_buf_size;
  obj->iso_time_str[str_index++] = '+';
  obj->iso_time_str[str_index++] = '0';
  obj->iso_time_str[str_index++] = '8';
  obj->iso_time_str[str_index++] = '0';
  obj->iso_time_str[str_index++] = '0';

  return RT_EOK;
}// 构建iso时间字符串

// 从内部RTC构建时间字符串
rt_err_t Build_Innner_Rtc_Time_Interface(Rtc_Time_Def *obj) {
  int str_index;
  int int_size;
  char str_buf[12];
  stc_rtc_date_t pstcRtcDate;
  RTC_GetDate(RTC_DATA_FMT_DEC, &pstcRtcDate);
  stc_rtc_time_t pstcRtcTime;
  RTC_GetTime(RTC_DATA_FMT_DEC, &pstcRtcTime);

  memcpy(obj->iso_time_str, "20", 2);
  str_index += 2;

  int_size = itoa(pstcRtcDate.u8Year, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = '-';

  int_size = itoa(pstcRtcDate.u8Month, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = '-';

  int_size = itoa(pstcRtcDate.u8Day, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = 'T';

  int_size = itoa(pstcRtcTime.u8Hour, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = ':';

  int_size = itoa(pstcRtcTime.u8Minute, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = ':';

  int_size = itoa(pstcRtcTime.u8Second, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = '.';

  int_size = itoa(ms_cnt, str_buf, 2);
  memcpy(obj->iso_time_str + str_index, str_buf, int_size);
  str_index += int_size;
  obj->iso_time_str[str_index++] = '+';
  obj->iso_time_str[str_index++] = '0';
  obj->iso_time_str[str_index++] = '8';
  obj->iso_time_str[str_index++] = '0';
  obj->iso_time_str[str_index++] = '0';

  return RT_EOK;
}// 从内部RTC构建时间字符串

// 读取外部RTC时间。
rt_err_t Read_Ext_Rtc_Time_Interface(Rtc_Time_Def *obj) {
  // 锁定资源。
  uint8_t get_mutex = 0;
  while (rt_mutex_take(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock), 50 * (2 ^ get_mutex)) != RT_EOK) {
    if (get_mutex >= 3) {
      return LL_ERR_BUSY;
    }
    get_mutex++;
  }

  Sd3078_Read_Data_Time(obj);


  // 释放资源
  rt_mutex_release(&(ext_rtc_ctrl.i2c_ctrl_obj->port_lock));

  return RT_EOK;
}// 读取外部RTC时间。

// 初始化外部RTC
void Init_Ext_Clock(void) {
  // SD3078默认开始32.768K时钟输出
  STATU_SET(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_32K_NVIC);

  if (strlen(i2c1_ctrl.name) == 0) {
    Init_I2c_Ctrl(&i2c1_ctrl, "i2c1_ctrl");
  }

  ext_rtc_ctrl.i2c_ctrl_obj = &i2c1_ctrl;
  ext_rtc_ctrl.cm_i2c = CM_I2C1;
  rt_sem_init(&(ext_rtc_ctrl.rtc_sem), "rtc sem", 0, RT_IPC_FLAG_PRIO);
  rt_sem_init(&(ext_rtc_ctrl.ext_rtc_start_intc), "rtc sec start sem", 0, RT_IPC_FLAG_PRIO);
  rt_sem_init(&(ext_rtc_ctrl.ext_rtc_half_intc), "rtc sec half sem", 0, RT_IPC_FLAG_PRIO);

  {// 初始化外部RTC芯片
    Sd3078_Write_Enable();
    SWDT_FeedDog();
    rt_thread_mdelay(2);
    Sd3078_Init_Sec_Intc();
    SWDT_FeedDog();
    rt_thread_mdelay(2);
    Sd3078_Start_Sec_Intc();
    SWDT_FeedDog();
    rt_thread_mdelay(2);
    Sd3078_Write_Disable();
  }// 初始化外部RTC芯片

  // 切换外部32.768时钟
  LL_PERIPH_WE(LL_PERIPH_ALL);
  BSP_XTAL32_Init();
  LL_PERIPH_WP(LL_PERIPH_ALL);
}// 初始化外部RTC

_ARMABI clock_t clock(void) {
  return SysTick_GetTick();
}

// RTC任务运行函数
void Thread_Rtc_Run(void *parmameter) {
  // 初始化外部rtc管理对象
  if (ext_rtc_time.Build_Innner_Rtc_Time == NULL || ext_rtc_time.Build_Rtc_Time_Str == NULL || ext_rtc_time.Read_Ext_Rtc_Time == NULL) {
    Init_Rtc_Time_Obj(&ext_rtc_time);
  }

  // 初始化内部rtc管理对象
  if (inner_rtc_time.Build_Innner_Rtc_Time == NULL || inner_rtc_time.Build_Rtc_Time_Str == NULL || inner_rtc_time.Read_Ext_Rtc_Time == NULL) {
    Init_Rtc_Time_Obj(&inner_rtc_time);
  }

  // 检查内部RTC是否初始化完成
  if (STATU_GET_NOT(inner_rtc_status, RTC_INITED)) {
    App_RTCCfg();
  }

  // 初始化外部RTC
  if (STATU_GET_NOT(ext_rtc_ctrl.ext_rtc_status, EXT_RTC_INITED)) {
    Init_Ext_Clock();
  }

  for (;;) {// rtc任务主循环
    completion_wait(&(ext_rtc_ctrl.ext_rtc_start_intc), RT_WAITING_FOREVER);
    rt_kprintf("start a rtc task\n");
    rt_thread_yield();
    SWDT_FeedDog();
  }// rtc任务主循环

}// RTC任务运行函数

// 	RTC外部中断输入回调函数
void INT_SRC_PORT_EIRQ10_IrqCallback(void) {

  if (GPIO_ReadInputPins(RTC_INT_PORT, RTC_INT_PIN) == PIN_SET) {
    TMRA_Stop(CM_TMRA_1);
    TMRA_SetCountValue(CM_TMRA_1, 0x30D4U);
    TMRA_Start(CM_TMRA_1);
    ms_cnt = 0;
    completion_done(&(ext_rtc_ctrl.ext_rtc_start_intc));
    rt_kprintf("get a rtc sec invc start!\n");
    rt_kprintf("get ms: %d\n", ms_cnt);
    TRNG_Start();
  } else {
    rt_kprintf("get a rtc sec invc half!\n");
    rt_kprintf("get ms: %d\n", ms_cnt);
    completion_done(&(ext_rtc_ctrl.ext_rtc_half_intc));
    TRNG_Start();
  }
}// 	RTC外部中断输入回调函数

// 内部RTC周期中断
void INT_SRC_RTC_PRD_IrqCallback(void) {
  rt_kprintf("get a rtc pre hour invc start!\n");
}

// 内部RTC闹钟中断。每天0点启动
void INT_SRC_RTC_ALM_IrqCallback(void) {
  rt_kprintf("get a rtc alert invc at 00:00:00 !\n");
}
